

<!DOCTYPE html>
<html lang="zh" xmlns:v-bind="http://www.w3.org/1999/xhtml">

<head><meta name="generator" content="Hexo 3.9.0">
    <title>express试水（1）「大淘客api」😎 - suke`s Notice</title>
<meta charset="utf-8">
<meta name="X-UA-Compatible" content="IE=edge">
<meta name="author" content="suke">
<meta name="description" content="安装
npm init


npm install express –save

快速生成项目
npm insta...">
<meta name="keywords" content="javascript html css php server npm nodejs">

<link rel="alternate" type="application/atom+xml" title="ATOM 1.0" href="/atom.xml">

    <meta charset="utf-8">
    <meta name="X-UA-Compatible" content="IE=edge">
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
    <meta content="telephone=no" name="format-detection">
    <meta name="renderer" content="webkit">
    <meta name="theme-color" content="#ffffff">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha256-eSi1q2PG6J7g7ib17yAaWMcrr5GrtohYChqibrV7PBE=" crossorigin="anonymous">
<link rel="stylesheet" href="/css/journal.css?21136756">

<script src="/js/loadCSS.js"></script>
<script>
    loadCSS("https://fonts.googleapis.com/css?family=Lora|Montserrat|Fira+Mono|Material+Icons");
    (function (d) {
        var config = {
                kitId: 'dwg1tuc',
                scriptTimeout: 3000,
                async: true
            },
            h = d.documentElement, t = setTimeout(function () {
                h.className = h.className.replace(/\bwf-loading\b/g, "") + " wf-inactive";
            }, config.scriptTimeout), tk = d.createElement("script"), f = false,
            s = d.getElementsByTagName("script")[0], a;
        h.className += " wf-loading";
        tk.src = 'https://use.typekit.net/' + config.kitId + '.js';
        tk.async = true;
        tk.onload = tk.onreadystatechange = function () {
            a = this.readyState;
            if (f || a && a != "complete" && a != "loaded") return;
            f = true;
            clearTimeout(t);
            try {
                Typekit.load(config)
            } catch (e) {
            }
        };
        s.parentNode.insertBefore(tk, s)
    })(document);
</script>
<noscript>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lora|Montserrat|Anonymous+Pro:400|Material+Icons">
</noscript>
</head>
<body>
<div id="top"></div>
<div id="app">
<div class="single-column-drawer-container" ref="drawer" v-bind:class="{ 'single-column-drawer-container-active': isDrawerOpen }">
    <div class="drawer-content">
        <div class="drawer-menu">
            <a class="a-block drawer-menu-item false" href="https://sukeai.netlify.com">
                Home
            </a>
            

            
            
            <a class="a-block drawer-menu-item false" href="/firends/index.html">
                朋友👬
            </a>
            
            <a class="a-block drawer-menu-item false" href="/projects/index.html">
                空闲下来做的项目
            </a>
            
            <a class="a-block drawer-menu-item false" href="/about/index.html">
                关于我
            </a>
            

            
            <a class="a-block drawer-menu-item" href="/atom.xml">
                RSS
            </a>
            
        </div>
    </div>
</div>
<transition name="fade">
    <div v-bind:class="{ 'single-column-drawer-mask': mounted }" v-if="isDrawerOpen" v-on:click="toggleDrawer"></div>
</transition>
<nav ref="navBar" class="navbar sticky-top navbar-light single-column-nav-container">
    <div ref="navBackground" class="nav-background"></div>
    <div class="container container-narrow nav-content">
        <button id="nav_dropdown_btn" class="nav-dropdown-toggle" type="button" v-on:click="toggleDrawer">
            <i class="material-icons">
                menu
            </i>
        </button>
        <a ref="navTitle" class="navbar-brand" href="/">
            suke`s Notice
        </a>
    </div>
</nav>
<div class="single-column-header-container" ref="pageHead" v-bind:style="{ transform: 'translateZ(0px) translateY('+.3*scrollY+'px)', opacity: 1-navOpacity }">
    <a href="/">
        <div class="single-column-header-title">suke`s Notice</div>
        <div class="single-column-header-subtitle">hexo博客</div>
    </a>
</div>
<div ref="sideContainer" class="side-container">
    <a class="a-block nav-head false" href="/">
        <div class="nav-title">
            有猫病.
        </div>
        <div class="nav-subtitle">
             她的眼里有光,她爱的人是谁呢 
        </div>
    </a>

    <div class="nav-link-list">
        

        
        
        <a class="a-block nav-link-item false" href="/firends/index.html">
            朋友👬
        </a>
        
        <a class="a-block nav-link-item false" href="/projects/index.html">
            空闲下来做的项目
        </a>
        
        <a class="a-block nav-link-item false" href="/about/index.html">
            关于我
        </a>
        

        
        <a class="a-block no-tint nav-link-item" href="/atom.xml">
            RSS
        </a>
        
    </div>

    
    <div class="nav-footer">
        Proudly published with Hexo<br>
        
        Theme <a href="https://github.com/SumiMakito/hexo-theme-journal/" target="_blank" rel="noreferrer noopener">Journal.</a> by <a href="https://mak1t0.cc/" target="_blank" rel="noreferrer noopener">Makito</a><br>
        
        &copy; 2020 <a href="https://sukeai.netlify.com">suke`s Notice</a>
    </div>
</div>
<div ref="extraContainer" class="extra-container">
    <div class="pagination">
        <a id="globalBackToTop" class="pagination-action animated-visibility" href="#top" :class="{ invisible: scrollY == 0 }">
            <i class="material-icons pagination-action-icon">
                keyboard_arrow_up
            </i>
        </a>

        
    </div>
</div>



<div ref="streamContainer" class="stream-container">
    <div class="post-list-container post-list-container-shadow">
        <div class="post">
            <div class="post-head-wrapper" style="background-image: url('https://tva1.sinaimg.cn/large/006y8mN6gy1g9enb2rw4ij30zv08rtb1.jpg')">
                <div class="post-title">
                    express试水（1）「大淘客api」😎
                    <div class="post-meta">
                        <time datetime="2019-11-27T12:00:00.000Z" itemprop="datePublished">
                            2019-11-27 12:00
                        </time>&nbsp;
                        
    
                        
                        
                        <i class="material-icons" style>label</i>
                        
                        <a href="/tags/express/">express</a>, 
                        
                        <a href="/tags/javascript/">javascript</a>
                        
                        
                    </div>
                </div>
            </div>
    
            <div class="post-body-wrapper">
                <div class="post-body">
                    <h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><blockquote>
<p>npm init</p>
</blockquote>
<blockquote>
<p>npm install express –save</p>
</blockquote>
<h2 id="快速生成项目"><a href="#快速生成项目" class="headerlink" title="快速生成项目"></a>快速生成项目</h2><blockquote>
<p>npm install -g express-generator</p>
</blockquote>
<blockquote>
<p>express newApp</p>
</blockquote>
<h1 id="基础目录"><a href="#基础目录" class="headerlink" title="基础目录"></a>基础目录</h1><p><img src="https://tva1.sinaimg.cn/large/006y8mN6gy1g9eofwkq2mj30950dsdgq.jpg" alt></p>
<h3 id="bin-www"><a href="#bin-www" class="headerlink" title="bin/www"></a><code>bin/www</code></h3><p>www配置文件，某些插件会把log文件写在这里</p>
<h3 id="public"><a href="#public" class="headerlink" title="public"></a><code>public</code></h3><p>静态资源文件，需要在入口文件挂载才可以访问</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//static是一个虚拟目录 可以直接用 root目录</span><br><span class="line">app.use(&apos;/static&apos;,express.static(path.join(__dirname, &apos;public&apos;)));</span><br></pre></td></tr></table></figure>

<h3 id="routes"><a href="#routes" class="headerlink" title="routes"></a><code>routes</code></h3><p>路由文件</p>
<h3 id="views"><a href="#views" class="headerlink" title="views"></a><code>views</code></h3><p>模板文件，可自定义程度很高 还没有详细了解过，暂时倾向于前后端分离，只写接口在这里</p>
<h3 id="app-js"><a href="#app-js" class="headerlink" title="app.js"></a><code>app.js</code></h3><p>入口文件，大部分的配置都可以在这里完成<br>使用插件  cookie jsonparse 这些都需要引用插件实现，模板项目中已经生成了常用的插件<br>自定义模板<br>定义路由</p>
<h1 id="Curl接第三方接口"><a href="#Curl接第三方接口" class="headerlink" title="Curl接第三方接口"></a>Curl接第三方接口</h1><blockquote>
<p>这里使用大淘客的api做的尝试，没有具体项目逻辑想不到应该做什么，另外数据库也还没尝试</p>
</blockquote>
<h2 id="demo"><a href="#demo" class="headerlink" title="demo"></a>demo</h2><p><a href="https://github.com/Treblex/dataoke-api/blob/master/server/util/CommodityFactory.js" target="_blank" rel="noopener">https://github.com/Treblex/dataoke-api/blob/master/server/util/CommodityFactory.js</a></p>
<blockquote>
<p>新建一个文件夹放自己的工具类就可以，对文件夹结构没有强制对要求,对应的调用方法在 router/api.js</p>
</blockquote>
<h2 id="Request"><a href="#Request" class="headerlink" title="Request"></a>Request</h2><p>直接调用request模块就可以，使用方法也非常的简单，符合前端的习惯</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> request = <span class="built_in">require</span>(<span class="string">'request'</span>);</span><br><span class="line">request(&#123;data&#125;,callback=<span class="function">(<span class="params">err,res,body</span>)=&gt;</span>&#123;&#125;)</span><br></pre></td></tr></table></figure>

<h2 id="验签"><a href="#验签" class="headerlink" title="验签"></a>验签</h2><p>在大淘客的demo中，引用了corypt md5进行加密，这里需要注意不要在引用文件后就立即<code>createHash('md5')</code>，因为每个实例只能进行一次加密，在需要的地方<code>createHash('md5')</code>就可以了</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">crypto.createHash(&apos;md5&apos;)</span><br></pre></td></tr></table></figure>

<h2 id="调用"><a href="#调用" class="headerlink" title="调用"></a>调用</h2><p><a href="https://github.com/Treblex/dataoke-api/blob/master/server/routes/api.js" target="_blank" rel="noopener">https://github.com/Treblex/dataoke-api/blob/master/server/routes/api.js</a></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</span><br><span class="line"><span class="keyword">var</span> router = express.Router();</span><br><span class="line"><span class="keyword">var</span> factory = <span class="built_in">require</span>(<span class="string">'../util/CommodityFactory'</span>)</span><br><span class="line"><span class="comment">// 商品工厂对象</span></span><br><span class="line"><span class="keyword">let</span> CommodityFactory = <span class="keyword">new</span> factory(&#123;</span><br><span class="line">  appSecret: <span class="string">'17eda35413998548b3fdebd31e6d2c51'</span>,</span><br><span class="line">  appKey: <span class="string">'5dc6fcef48989'</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">// 临时写的</span></span><br><span class="line"><span class="keyword">const</span> errCode = <span class="function">(<span class="params">title</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    time: <span class="keyword">new</span> <span class="built_in">Date</span>() * <span class="number">1</span>,</span><br><span class="line">    code: <span class="number">-1</span>,</span><br><span class="line">    msg: title,</span><br><span class="line">    data: &#123;&#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 品牌</span></span><br><span class="line">router.get(<span class="string">'/get-brand-list'</span>, <span class="keyword">async</span> <span class="function"><span class="keyword">function</span> (<span class="params">req, res, next</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> &#123;</span><br><span class="line">    pageId,</span><br><span class="line">    pageSize = <span class="number">10</span></span><br><span class="line">  &#125; = req.query</span><br><span class="line"><span class="comment">//   req.query 请求的参数,</span></span><br><span class="line"><span class="comment">//   如果需要支持类似thinkphp的静态url   url地址可以写成  '/detail/:id'</span></span><br><span class="line"><span class="comment">//   取值使用 req.params['id'],如果有正则，正则的部分为 req.params[index]</span></span><br><span class="line">  <span class="keyword">if</span> (!pageId) &#123;</span><br><span class="line">    res.send(errCode(<span class="string">"pageId不可空"</span>))</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">let</span> body = <span class="keyword">await</span> CommodityFactory.getBarndList(&#123;</span><br><span class="line">    pageId,</span><br><span class="line">    pageSize</span><br><span class="line">  &#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//   返回页面显示的内容，在此之前可以设置返回的header 等一些常用内容</span></span><br><span class="line">  res.send(body)</span><br><span class="line"><span class="comment">//   res.render('index', &#123; title: 'Express' ,中文:"打火机卡上打哈电话接啊活动空间啊"&#125;);</span></span><br><span class="line"><span class="comment">// 渲染到模板的写法，第一个参数模板名字，第二个为渲染到模板的变量</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h1 id="中间件开发"><a href="#中间件开发" class="headerlink" title="中间件开发"></a>中间件开发</h1><p><a href="http://www.expressjs.com.cn/guide/writing-middleware.html" target="_blank" rel="noopener">官网文档&gt;&gt;</a></p>
<p>我的理解是中间件在php中类似于一个base控制器，</p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">loginBase</span></span>&#123;</span><br><span class="line">    <span class="comment">// 检查登录，跳转页面</span></span><br><span class="line">    <span class="keyword">if</span>(isLogin)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 301 login.html</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">home</span> <span class="keyword">extends</span> <span class="title">loginBase</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> home</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src="https://tva1.sinaimg.cn/large/006y8mN6gy1g9eotnxbkaj30tk0iswkf.jpg" alt><br>像文档中介绍的，其实我们定义的路由也是中间件<br>我能想到的常用的业务场景就是像上边的 登录检测，用户权限这些</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">app.use(<span class="string">'/api'</span>,(res,req,next)=&gt;&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'==err==||AppBase 登录检测或一些其他的内容'</span>);</span><br><span class="line">  <span class="keyword">let</span> islogin = <span class="literal">false</span></span><br><span class="line">  <span class="keyword">if</span>(!islogin)&#123;</span><br><span class="line">    req.send(<span class="string">'err 未登录什么的'</span>),<span class="comment">//如果不执行下一步业务逻辑，我们就必须结束请求，而不能直接return，否则页面会一直处于加载中，直到请求超时</span></span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  next();<span class="comment">//执行下一步  api的路由文件</span></span><br><span class="line">&#125;)</span><br><span class="line">app.use(<span class="string">'/api'</span>, apiRouter);<span class="comment">//自定义路由  业务逻辑</span></span><br></pre></td></tr></table></figure>

<h1 id="End"><a href="#End" class="headerlink" title="End"></a>End</h1><p>还没有部署，客户端没写，接口都对了，下面是github仓库<br><a href="https://github.com/Treblex/dataoke-api" target="_blank" rel="noopener">https://github.com/Treblex/dataoke-api</a></p>
<p>其实遇到一个问题没有解决，request大淘客接口的时候又一个 version参数，这个参数有的接口是1.0.0 有的是1.0.1，而且有过期验证，过期的版本无法使用，对于怎么更新接口版本和过期通知没有太好解决方法，现在version是在factory的每个请求里边写的默认参数</p>

                </div>
            </div>
    
            <nav class="post-pagination">
    
    <a class="newer-posts" href="/2019-11-28/uniapp快速开发常用工具「1」.html">
        Previous post<br>uniapp快速开发常用工具「1」🔧 📦
    </a>
    
    <span class="page-number"></span>
    
    <a class="older-posts" href="/2019-08-23/分割一个长数组至-n-个-len-长度的小数组.html">
        Next post<br>分割一个长数组至 n 个 len 长度的小数组
    </a>
    
</nav>

    
            


        </div>
    </div>
    <div class="single-column-footer">
    Proudly published with Hexo<br>
    
    Theme <a href="https://github.com/SumiMakito/hexo-theme-journal/" target="_blank" rel="noreferrer noopener">Journal.</a> by <a href="https://mak1t0.cc/" target="_blank" rel="noreferrer noopener">Makito</a><br>
    
    &copy; 2020 <a href="https://sukeai.netlify.com">suke`s Notice</a>
</div>
</div>

</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.4/dist/umd/popper.min.js" integrity="sha256-EGs9T1xMHdvM1geM8jPpoo8EZ1V1VRsmcJz8OByENLA=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js" integrity="sha256-VsEqElsCHSGmnmHXGQzvoWjWwoznFSZc6hs7ARLRacQ=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js" integrity="sha256-FtWfRI+thWlNz2sB3SJbwKx5PgMyKIVgwHCTwa3biXc=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/smooth-scroll@14.2.1/dist/smooth-scroll.polyfills.min.js" integrity="sha256-CI4Gq5E0io1Pv0xM3qPM+NUIOhbIBvC3GiN1Y4KhXpw=" crossorigin="anonymous"></script>
<script src="/js/journal.js?93092175"></script>



</body>
</html>
